package org.raymond.iworks.study.basic.thread.cyclicbarrier;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

@Slf4j
public class Demo1 {
    public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
       test1();
    }

    public static void test1() throws BrokenBarrierException, InterruptedException {
        // 所有指定的线程都到达await点后触发barrierAction线程
        CyclicBarrier cyclicBarrier1 = new CyclicBarrier(3, ()->{
            log.info("所有工作都结束,可以汇总报告了");
        });
        // 没有barrierAction,其他线程执行逻辑是一样的
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
        Thread t1 = new Thread(()->{
            try {
                log.info("到达栅栏1");
                Thread.sleep(500);
                cyclicBarrier.await();
                log.info("突破栅栏1 1次");
                Thread.sleep(1000);
                cyclicBarrier.await();
                log.info("突破栅栏1 2次");
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        });
        Thread t2 = new Thread(()->{
            try {
                log.info("到达栅栏2");
                Thread.sleep(1500);
                cyclicBarrier.await();
                log.info("突破栅栏2 1次");
                Thread.sleep(2000);
                cyclicBarrier.await();
                log.info("突破栅栏2 2次");
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        });
        Thread t3 = new Thread(()->{
            try {
                log.info("到达栅栏3");
                Thread.sleep(2500);
                cyclicBarrier.await();
                log.info("突破栅栏3 1次");
                Thread.sleep(3000);
                cyclicBarrier.await();
                log.info("突破栅栏3 2次");
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        });
        t1.start();
        t2.start();
        t3.start();
    }

    // 每一轮循环计数,一个线程里只能await一次,就要等待其他线程都await,才能开始下一轮
    public static void test2() throws BrokenBarrierException, InterruptedException {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(1, ()->{
            log.info("结束了");
        });
        cyclicBarrier.await();
        Thread t1 = new Thread(()-> {
            try {
                cyclicBarrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        });
        t1.start();
    }
}
